package com.safety.algorithm.eigenvalue;

import java.util.*;

public class EigenvalueAlgorithm {
    //计算平均值
    //能量,频次,强度,瓦斯涌出变化率,由element传入
    public static double average(List<Map<String, Object>> lists, String element) {
        double sum = 0;
        double count = lists.size();
        for (Map<String, Object> map : lists) {
            if (!map.containsKey(element) || map.get(element).equals(-1)) {
                count--;
            } else {
                sum += Double.parseDouble(map.get(element).toString());
            }
        }
        if (element.equals("enSum")) {
            return sum;
        } else {
            return count != 0 ? sum / count : 0;
        }
    }

    public static double average(List<Double> lists) {
        double sum = 0;
        double count = lists.size();
        for (int i = 0; i < count; i++) {
            sum += lists.get(i);
        }

        return count == 0 ? 0 : sum / count;
    }

    //每日累计能量，平均能量，最大能量

    /**
     * @Description:
     * @Param: [lists]
     * @return: java.util.List<java.util.Map                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               <                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               java.lang.String                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               ,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               java.lang.Object>>
     * @Author: ChengQi
     * @Date: 2018/12/26
     */
    public static Map<String, Object> microseismEveryday(List<Map<String, Object>> lists, String dateTime) {
        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
        double maxx = -1;
        double sum = 0;
        int count = lists.size();
        for (int i = 0; i < count; i++) {
            Map<String, Object> map = lists.get(i);
            if (map.get("emergoa").equals(-1)) {
                count--;
            } else {
                maxx = Math.max(maxx, Double.parseDouble(map.get("emergoa").toString()));
                sum += Double.parseDouble(map.get("emergoa").toString());
            }
        }

        Map<String, Object> map = new HashMap<String, Object>(6);
        map.put("sum", sum);
        map.put("average", count != 0 ? sum / count : 0);
        map.put("max", maxx);
        map.put("frequency", count);
        return map;
    }


    //偏差值,变化率
    //微震能量，微震频次，地音能量，地音频次，电磁强度，声发射强度,瓦斯涌出变化率
    //enNow 这一刻的能量（频次，强度），enAverage 两次大能量事件之间的平均值（n小时的平均值）
    public static double dev(double enNow, double enAverage, double a) {
        return enAverage != 0 ? enNow / enAverage + a : 0;
    }

    //趋势预警指标
    //电磁辐射，声发射，瓦斯
    public static double warnings(double v1, double v2, double dt) {
        return dt != 0 ? Math.abs(v1 - v2) / dt : 0;
    }


    //离散度 加权平均距离
    //计算  加权平均距离，传入所有历史数据
    public static List<Map<String, Object>> criticalCharacteristicEn(List<Map<String, Object>> lists) {
        double xi;
        double yi;
        double zi;
        double wi;//能量权重
        double avgX;
        double avgY;
        double avgZ;
        double d;//加权平均距离
        double moleculeX = 0;//X加权平均距离分子
        double moleculeY = 0;//Y加权平均距离分子
        double moleculeZ = 0;//Z加权平均距离分子
        double sumWi = 0;//能量权重和
        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
        //计算avgX，avgY，avgZ,sumWi
        for (Map<String, Object> map : lists) {
            moleculeX += Math.sqrt(Double.parseDouble(map.get("emergoa").toString()))
                    * Double.parseDouble(map.get("x").toString());
            moleculeY += Math.sqrt(Double.parseDouble(map.get("emergoa").toString()))
                    * Double.parseDouble(map.get("y").toString());
            moleculeZ += Math.sqrt(Double.parseDouble(map.get("emergoa").toString()))
                    * Double.parseDouble(map.get("z").toString());
            sumWi += Math.sqrt(Double.parseDouble(map.get("emergoa").toString()));
        }
        avgX = moleculeX / sumWi;
        avgY = moleculeY / sumWi;
        avgZ = moleculeZ / sumWi;
        //计算加权平均距离
        for (Map<String, Object> map : lists) {
            xi = Double.parseDouble(map.get("x").toString());
            yi = Double.parseDouble(map.get("y").toString());
            zi = Double.parseDouble(map.get("z").toString());
            wi = Math.sqrt(Double.parseDouble(map.get("emergoa").toString()));
            d = Math.sqrt(Math.pow(xi - avgX, 2) * wi / sumWi + Math.pow(yi - avgY, 2) * wi / sumWi + Math.pow(zi - avgZ, 2) * wi / sumWi);
            map.put("d", d);
            result.add(map);
        }
        return result;
    }

    //    //求七组临界特征能量
    public static List<Map<String, Object>> sevenEn(List<Map<String, Object>> lists) {
        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
        Map<String, Object> resultMap = new HashMap<String, Object>();
        double[] dotNum = {1.2, 7.04, 27.5, 80.84, 88.51, 94.84, 98.34};
        int[] start = {40, 45, 98, 98, 98, 90, 85};
        int[] end = {45, 50, 99, 99, 99, 98, 90};
        double sumFE = 0;
        double avgD;
        double En[] = new double[lists.size()];
        int No;//表示第几组数据
        for (int i = 0; i < 7; i++) {
            //分别求七组值的临界特征能量
            No = (int) Math.round(lists.size() * 0.01 * dotNum[i]);
            int j = No;
            int k = 0;//En数组计数
            avgD = Double.parseDouble(lists.get(No).get("d").toString());
            //向左遍历找一米以内的值
            for (j = No - 1; j >= 0; j--) {
                if (Math.abs(Double.parseDouble(lists.get(j).get("d").toString()) - avgD) > 1)
                    break;
                k++;
                En[k] = Double.parseDouble(lists.get(No).get("emergoa").toString());
            }
            //向右遍历找一米以内的值
            for (j = No; ; j++) {
                if (Math.abs(Double.parseDouble(lists.get(j).get("d").toString()) - avgD) > 1)
                    break;
                k++;//En的长度为k
                En[k] = Double.parseDouble(lists.get(No).get("emergoa").toString());
            }
            //从小到大排序En数组
            Arrays.sort(En);
            //按照七个范围内的特征能量求平均值。(7个范围需要前端传值，此数据为默认值)
            start[0] = (int) Math.round(k * 0.01 * start[i]);//第j个范围的开始
            end[0] = (int) Math.round(k * 0.01 * end[i]);//第j个范围的结束
            for (k = start[0]; k <= end[0]; k++) {
                sumFE += En[k];
            }
            resultMap.put("e", sumFE / (end[0] - start[0]));
            resultMap.put("d", avgD);
            result.add(resultMap);
        }
        return result;
    }

    //临时代替一下曲线函数
    private static double test(double a) {
        return 1;
    }

    //离散度 特征能量 离散度I
    //传入八小时的能量数据，（从大到小排序），计算特征能量，然后算出离散度I
    public static double characteristicEn(List<Map<String, Object>> lists) {
        double charaEn;//特征能量
        double weightingEn;//加权特征能量
        double avgD;//加权平均距离
        double avgX = 0;
        double avgY = 0;
        double avgZ = 0;
        double molecule = 0;//加权平均距离分子
        double denominator = 0;//加权平均距离分母
        double wi = 0;//微震事件能量的开方值
        int len = lists.size();
        //计算特征能量
        if (len % 2 == 0) {
            charaEn = Double.parseDouble(lists.get(0).get("emergoa").toString())
                    + (Double.parseDouble(lists.get(len / 2 + 1).get("emergoa").toString())
                    + Double.parseDouble(lists.get(len / 2).get("emergoa").toString()));
        } else {
            charaEn = Double.parseDouble(lists.get(0).get("emergoa").toString())
                    + Double.parseDouble(lists.get(len / 2).get("emergoa").toString());
        }
        //计算加权平均距离
        for (Map<String, Object> map : lists) {
            avgX += Double.parseDouble(map.get("x").toString());
            avgY += Double.parseDouble(map.get("y").toString());
            avgZ += Double.parseDouble(map.get("z").toString());
        }
        avgX /= len;
        avgY /= len;
        avgZ /= len;
        for (Map<String, Object> map : lists) {
            wi = Math.sqrt(Double.parseDouble(map.get("emergoa").toString()));
            denominator += wi;
            molecule += wi * (Math.pow((Double.parseDouble(map.get("x").toString()) - avgX), 2)
                    + Math.pow((Double.parseDouble(map.get("y").toString()) - avgY), 2)
                    + Math.pow((Double.parseDouble(map.get("z").toString()) - avgZ), 2));
        }
        avgD = Math.sqrt(molecule / denominator);
        //计算对应的临界特征能量
        weightingEn = test(avgD);
        return Math.log(charaEn / weightingEn + 1);
    }


    //微震频次比
    public static double freRatio(double molecule, double denominator) {
        return denominator != 0 ? molecule / denominator : 0;
    }

    //脉冲因子
    public static double pulseFactor(double molecule, double denominator) {
        return denominator != 0 ? 10 * molecule / denominator : 0;
    }

    //液压闪烁函数
    //传入平均值，还有flag
    public static boolean flicker(double en, double avg, boolean flag) {
        double avgLow = avg * 0.1;
        if (flag) {
            return en < avgLow;
        } else {
            return en > avg;
        }
    }


    //闪烁间隔危险度
    //传入两个时间，返回危险度
    public static long hydraulicSupRiskDegree(Date t1, Date t2) {
        return (t2.getTime() - t1.getTime()) >= 0 ? (60 * 60 * 1000) / (t2.getTime() - t1.getTime()) : 0;
    }


    //判断偏离异常，偏差高值总数
    //可以用来完成偏离异常持续时间，偏离异常累计时间，偏离异常频次
    //时间间隔为m，默认为3
    //电磁辐射偏离异常,阈值为a，a默认值0.5,返回True为+m，返回False为归零
    //声发射偏离异常,阈值为b，b默认值20,返回True为+m，返回False为归零
    //地音每日能量偏差高值总数,阈值为2,返回True为+1
    //地音每日脉冲偏差高值总数,阈值为2,返回True为+1

    /**
     * @Description:
     * @Param: [Dev, a, type]
     * @return: boolean
     * @Author: ChengQi
     * @Date: 2018/12/25
     */
    public static boolean devAbnormal(double Dev, double a, int type) {
        if (type == 1) {
            return Dev >= a;
        } else {
            return Dev > a;
        }
    }

    /**
     * @Description: 电：n小时偏差值
     * @Param: [divisor  除数, dividend    被除数, diff   差值]
     * @return: void
     * @Author: ChengQi
     * @Date: 2018/12/25
     */
    public static double divide(double divisor, double dividend, double diff) {
        if (dividend == 0) {
            return 0;
        } else {
            return divisor / dividend + diff;
        }
    }

    //绝对瓦斯涌出量
    //q 瓦斯浓度，v 风速，s 巷道断面面积
    public static double gasAbsEmission(double q, double v, double s) {
        return q * v * s;
    }
}
